const { DataTypes } = require('sequelize');
const { sequelize } = require('../config/database');
const { logInfo, logError, logWarning } = require('../logger');
const bcrypt = require('bcrypt');

// 盐值轮数
const SALT_ROUNDS = 12;

/**
 * User model definition
 */
const User = sequelize.define('User', {
  id: {
    type: DataTypes.BIGINT,
    primaryKey: true,
    autoIncrement: true
  },
  uuid: {
    type: DataTypes.STRING(36),
    unique: true
  },
  username: {
    type: DataTypes.STRING(50),
    unique: true
  },
  email: {
    type: DataTypes.STRING(100),
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true
    }
  },
  phone: {
    type: DataTypes.STRING(20),
    unique: true
  },
  name: {
    type: DataTypes.STRING(255),
    allowNull: false
  },
  password_hash: {
    type: DataTypes.STRING(255),
    allowNull: false,
    field: 'password_hash'
  },
  // 添加对数据库中password字段的映射，但不直接使用它
  password: {
    type: DataTypes.VIRTUAL,
    set(value) {
      // 当设置password字段时，实际设置password_hash
      if (value) {
        throw new Error('不能直接设置password字段，请使用password_hash');
      }
    },
    get() {
      // 不返回实际的密码哈希值
      return undefined;
    }
  },
  avatarUrl: {
    type: DataTypes.STRING(255)
  },
  birthDate: {
    type: DataTypes.DATEONLY
  },
  birthTime: {
    type: DataTypes.TIME
  },
  gender: {
    type: DataTypes.ENUM('male', 'female', 'unknown')
  },
  timezone: {
    type: DataTypes.STRING(50)
  },
  isVip: {
    type: DataTypes.BOOLEAN,
    defaultValue: false
  },
  vipExpiresAt: {
    type: DataTypes.DATE
  },
  created_at: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  },
  updated_at: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  },
  createdAt: {
    type: DataTypes.VIRTUAL,
    get() {
      return this.getDataValue('created_at');
    }
  },
  updatedAt: {
    type: DataTypes.VIRTUAL,
    get() {
      return this.getDataValue('updated_at');
    }
  }
}, {
  tableName: 'users',
  timestamps: true,
  indexes: [
    {
      unique: true,
      fields: ['uuid']
    },
    {
      unique: true,
      fields: ['username']
    },
    {
      unique: true,
      fields: ['email']
    },
    {
      unique: true,
      fields: ['phone']
    },
    {
      fields: ['isVip']
    }
  ]
});

/**
 * UserSubscription model definition
 */
const UserSubscription = sequelize.define('UserSubscription', {
  id: {
    type: DataTypes.BIGINT,
    primaryKey: true,
    autoIncrement: true
  },
  userId: {
    type: DataTypes.BIGINT,
    allowNull: false,
    references: {
      model: 'users',
      key: 'id'
    }
  },
  planId: {
    type: DataTypes.STRING,
    allowNull: false
  },
  status: {
    type: DataTypes.ENUM('pending', 'active', 'expired', 'cancelled'),
    defaultValue: 'pending'
  },
  startDate: {
    type: DataTypes.DATE,
    allowNull: false
  },
  endDate: {
    type: DataTypes.DATE,
    allowNull: false
  },
  autoRenew: {
    type: DataTypes.BOOLEAN,
    defaultValue: true
  },
  transactionId: {
    type: DataTypes.STRING,
    allowNull: true
  },
  createdAt: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  },
  updatedAt: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  }
}, {
  tableName: 'user_subscriptions',
  timestamps: true,
  indexes: [
    {
      fields: ['userId']
    },
    {
      fields: ['status']
    },
    {
      fields: ['planId']
    },
    {
      fields: ['endDate']
    }
  ]
});

// Define associations
User.hasMany(UserSubscription, {
  foreignKey: 'userId',
  as: 'subscriptions'
});

UserSubscription.belongsTo(User, {
  foreignKey: 'userId',
  as: 'user'
});

/**
 * Initialize database and sync models
 */
async function initDatabase() {
  try {
    await sequelize.authenticate();
    logInfo('Database connection established successfully');
    
    // Don't sync models with database to prevent altering existing tables
    // Models should match the existing database structure
    logInfo('Database initialization completed without model synchronization');
  } catch (error) {
    logError('Error initializing database:', error);
    throw error;
  }
}

/**
 * Check if user is VIP
 * @param {number} userId - User ID
 * @returns {Promise<boolean>} - Whether user is VIP
 */
User.isVipUser = async function(userId) {
  try {
    const user = await User.findByPk(userId);
    if (!user) {
      logWarning(`User not found: ${userId}`);
      return false;
    }
    
    // Check if user is marked as VIP and expiration date is valid
    if (user.isVip && user.vipExpiresAt) {
      const now = new Date();
      const expiresAt = new Date(user.vipExpiresAt);
      return expiresAt > now;
    }
    
    return false;
  } catch (error) {
    logError(`Error checking VIP status for user ${userId}:`, error);
    return false;
  }
};

module.exports = {
  User,
  UserSubscription,
  initDatabase
};